<html>
    <head>
        <meta charset="utf-8">
        <script src="../dist/claygl.js"></script>

        <style>
            body{
                background: -webkit-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
            }
            #cubeColor {
                width: 100px;
                height: 100px;
                position: absolute;
                bottom: 10px;
                right: 10px;
            }
            #shape {
                position: absolute;
                left:0px;
                bottom: 0px;
            }
        </style>
    </head>
    <body style="margin:0px;">
        <canvas width="1200" height="640" id="main"></canvas>
        <div id="cubeColor" style="background-color: rgb(245, 50, 50);"></div>
        <div id="fps" style="position:absolute;left:10px;top:10px;color:white;"></div>
        <script>
            //----------------------------------
            // Prepare animation shape data
            //----------------------------------
            var canvas = document.createElement('canvas');
            canvas.id = 'shape';
            var SIZE = 50;
            canvas.width = SIZE;
            canvas.height = SIZE;
            var ctx = canvas.getContext('2d');
            function drawCross() {
                ctx.fillStyle = 'black';
                ctx.fillRect(0, 0, SIZE, SIZE);
                ctx.save()
                ctx.scale(0.6, 0.6);
                ctx.translate(10, 10);
                ctx.strokeStyle = 'white';
                ctx.beginPath();
                ctx.lineWidth = SIZE / 3.5;
                ctx.moveTo(0, 0);
                ctx.lineTo(SIZE, SIZE);
                ctx.stroke();

                ctx.moveTo(SIZE, 0);
                ctx.lineTo(0, SIZE);
                ctx.stroke();
                ctx.restore();
                return ctx.getImageData(0, 0, SIZE, SIZE).data;
            }

            function drawCheck() {
                ctx.fillStyle = 'black';
                ctx.fillRect(0, 0, SIZE, SIZE);

                ctx.scale(0.7, 0.7);
                ctx.translate(10, 10);
                ctx.strokeStyle = 'white';
                ctx.beginPath();
                ctx.lineWidth = SIZE / 3.5;
                ctx.moveTo(0, SIZE / 2);
                ctx.lineTo(SIZE / 2, SIZE / 1.2);

                ctx.lineTo(SIZE, SIZE / 10);
                ctx.stroke();

                return ctx.getImageData(0, 0, SIZE, SIZE).data;
            }

            document.body.appendChild(canvas);

            function pixelToPositionArray(pixels) {
                var position = [];
                for (var i = 0; i < pixels.length; i+=4) {
                    var r = pixels[i];
                    if (r < 128) {
                        continue;
                    }
                    var idx = i / 4;
                    var x = (idx % SIZE) / SIZE * 40 - 20;
                    var y = 20 - (idx / SIZE) / SIZE * 40;
                    var z = Math.random() * 6;

                    position.push([x, y, z]);
                }
                return position;
            }
            var crossPixels = drawCross();
            var checkPixels = drawCheck();

            var crossPosArr = pixelToPositionArray(crossPixels);
            var checkPosArr = pixelToPositionArray(checkPixels);

            var larger = checkPosArr.length < crossPosArr.length ? crossPosArr: checkPosArr;
            var smaller = larger == crossPosArr ? checkPosArr: crossPosArr;

            for (var i = smaller.length; i < larger.length; i++) {
                var random = smaller[Math.round(Math.random() * (smaller.length - 1))];
                random = random.slice();
                random[2] += Math.random() * 3;
                smaller[i] = random;
            }

            var positionArr = [];

            for (var i = 0; i < crossPosArr.length; i++) {
                positionArr[i] = crossPosArr[i].slice();
            }

            //----------------------------------
            // Prepare scene
            //----------------------------------
            var Shader = clay.Shader;

            var renderer = new clay.Renderer({
                canvas: document.getElementById('main')
            });
            var shadowMapPass = new clay.prePass.ShadowMap({
                // softShadow: clay.prePass.VSM
            });

            renderer.resize(window.innerWidth, window.innerHeight);
            var scene = new clay.Scene();
            var camera = new clay.camera.Perspective({
                aspect: renderer.getViewportAspect()
            });
            camera.position.set(0, 0, 40);

            var shader = clay.shader.library.get('clay.standard');

            var cubeMat = new clay.Material({
                shader: shader
            });

            var root = new clay.Node();
            scene.add(root);

            var cubeList = [];

            var gltfLoader = new clay.loader.GLTF();
            var cubeGeo = new clay.geometry.Cube();

            for (var i = 0; i < positionArr.length; i++) {
                var position = positionArr[i];
                var mesh = new clay.Mesh({
                    material: cubeMat,
                    geometry: cubeGeo
                });
                mesh.position.set(position[0], position[1], position[2]);

                mesh.rotation.rotateX(Math.random() * Math.PI * 2);
                mesh.rotation.rotateZ(Math.random() * Math.PI * 2);

                mesh.scale.set(0.5, 0.5, 0.5);
                root.add(mesh);

                cubeList.push(mesh);
            }

            var light = new clay.light.Directional({
                shadowResolution: 1024,
                shadowBias: 0.005,
                intensity: 0.7
            });
            light.position.set(0, 30, 30);
            light.lookAt(scene.position);
            scene.add(light);

            scene.add(new clay.light.Ambient({
                intensity: 0.3
            }));

            var timeline =  new clay.Timeline();
            timeline.start();

            timeline.on('frame', function(deltaTime) {

                var start = new Date().getTime();
                shadowMapPass.render(renderer, scene, camera);
                var drawInfo = renderer.render(scene, camera);
                var renderTime = new Date().getTime() - start;

                document.getElementById('fps').innerHTML =
                        Math.round(1000 / deltaTime) + '<br />'
                        + renderTime + '<br />';

                var color = document.getElementById('cubeColor').style.backgroundColor;
                color = color.match(/rgb\((.*?)\)/)[1].split(/\s*,\s*/).map(function(item) {
                    return parseInt(item) / 255;
                });

                for (var i = 0; i < cubeList.length; i++) {
                    cubeList[i].material.set('color', color);
                    var pos = positionArr[i];
                    clay.Quaternion.rotateY(cubeList[i].rotation, cubeList[i].rotation, deltaTime / 500);
                    clay.Vector3.set(cubeList[i].position, pos[0], pos[1], pos[2]);
                }
            });

            document.body.addEventListener('mousemove', function(e) {
                var dx = e.pageX - window.innerWidth / 2;

                root.rotation.identity().rotateY(dx / 1000);
            });

            var obj = {
                position: positionArr
            }

            var current = crossPosArr;
            setInterval(function() {
                var another = current == crossPosArr ? checkPosArr: crossPosArr;
                timeline.animate(obj)
                .when(1000, {
                    position: another
                }).start("CubicInOut");
                current = another;
            }, 4000);
        </script>
    </body>
</html>